`timescale 1ns / 1ns

module WR_interface(
input i_rst,
input i_clk, //时钟复位(64M, 低复位)
output wire o_WRflag, //正在进行读处理的标志位
input wr_trig,
input [7:0] WR_addr,
input [7:0] WR_data,
output wire o_WR_finish, //完成一次写动作
output wire o_chip_oe, //SJA1000的写有效信号，低有效
output wire [7:0] o_sja1000_data_wr, //SJA1000向CAN总线写的数据
output wire o_sja1000_wr_n, //按时序图输出
output wire o_sja1000_ale,
output wire o_sja1000_cs_n);
//写过程的rd, dir信号全程为高电平

//////////////////////////////////////////////////////////////////////////////
 localparam IDLER = 16'b0000_0000_0000_0000;
 localparam S1R = 16'b0000_0000_0000_0001;
 localparam S2R = 16'b0000_0000_0000_0010;
 localparam S3R = 16'b0000_0000_0000_0100;
 localparam S4R = 16'b0000_0000_0000_1000;
 localparam S5R = 16'b0000_0000_0001_0000;
 localparam S6R = 16'b0000_0000_0010_0000;
 localparam S7R = 16'b0000_0000_0100_0000;
 localparam S8R = 16'b0000_0000_1000_0000;
 localparam S9R = 16'b0000_0001_0000_0000;
 localparam S10R = 16'b0000_0010_0000_0000;
 localparam S11R = 16'b0000_0100_0000_0000;
 localparam S12R = 16'b0000_1000_0000_0000;
 localparam S13R = 16'b0001_0000_0000_0000;
 localparam S14R = 16'b0010_0000_0000_0000;
 localparam S15R = 16'b0100_0000_0000_0000;
 localparam S16R = 16'b1000_0000_0000_0000;
////////////////////////////////////////////////////////////////
reg wr_trig0,wr_trig1;
always@(posedge i_clk) begin
	if(i_rst) begin wr_trig1 <= 1'd0; wr_trig0 <= 1'd0; end 
	else begin wr_trig1 <= wr_trig0; wr_trig0 <= wr_trig; end end 
(* KEEP="TRUE" *)(* S="YES" *) wire wr_trig_r;
assign wr_trig_r = (~wr_trig0)&& wr_trig1;
////////////////////////////////////////////////////////////////
//锁存发进来的待写的存储器地址与数据
reg WRflag,WR_finish;
reg [7:0] WRdat, WRadd;
always@(posedge i_clk) begin
	if(i_rst) begin WRdat <= 1'd0; WRadd <= 1'd0; end 
	else if(WR_finish) begin WRdat <= 1'd0; WRadd <= 1'd0; end 
	else if(wr_trig) begin WRdat <= WR_data; WRadd <= WR_addr; end end 
////////////////////////////////////////////////////////////////
//主时钟二分频
wire dssck, dssck_rise;
reg [1:0] sck_cnt;
always @(posedge i_clk) begin
	if (i_rst) sck_cnt<=8'h0;
	else if (!i_rst) sck_cnt<=sck_cnt+1'b1;
	else sck_cnt<=8'h0; end
assign dssck = sck_cnt[1];
reg dssck_d1, dssck_d2;
always @(posedge i_clk) 
begin 
	if(i_rst) begin dssck_d1 <= dssck; dssck_d2 <= dssck_d1; end
	else begin dssck_d1 <= dssck; dssck_d2 <= dssck_d1; end
end
assign dssck_rise = dssck_d1 && (~dssck_d2);
/////////////////////////////////////////////////////////////////
reg [7:0] sja1000_data_wr;
reg chip_oe, sja1000_cs_n, sja1000_dir_1out;
reg sja1000_wr_n, sja1000_ale;
/////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////
reg [15:0] st;
(* KEEP="TRUE" *)(* S="YES" *) wire [15:0] st_temp;
assign st_temp = st;
always@(posedge i_clk) begin
	if(i_rst) begin 
		chip_oe <= 1'b0; sja1000_data_wr <= 8'h00; sja1000_dir_1out <= 1'b1;
		sja1000_ale <= 1'b0; sja1000_wr_n <= 1'b1; sja1000_cs_n <= 1'b1;
		WRflag <= 1'b0; WR_finish<= 1'b0; st<=IDLER; end
	else begin
		case(st)
			IDLER: begin
				chip_oe <= 1'b0; sja1000_data_wr <= 8'h00; sja1000_dir_1out <= 1'b1;
				sja1000_ale <= 1'b0; sja1000_wr_n <= 1'b1; sja1000_cs_n <= 1'b1;
				WRflag <= 1'b0; WR_finish<= 1'b0; if(wr_trig_r) st<=S1R; end
			S1R: begin if(dssck_rise) begin WRflag <= 1'b1; st<=S2R; end end
			S2R: begin if(dssck_rise) begin chip_oe <= 1'b1; st<=S3R; end end //OE,1
			S3R: begin if(dssck_rise) begin sja1000_data_wr <= WRadd; st<=S4R; end end //ADDR
			S4R: begin if(dssck_rise) begin sja1000_ale <= 1'b1; st<=S5R; end end //ALE,1 
			S5R: begin if(dssck_rise) begin st<=S6R; end end 
			S6R: begin if(dssck_rise) begin sja1000_ale <= 1'b0; st<=S7R; end end //ALE,0
			S7R: begin if(dssck_rise) begin sja1000_data_wr <=WRdat; st<=S8R; end end //DATA
			S8R: begin if(dssck_rise) begin sja1000_cs_n <= 1'b0; st<=S9R; end end //CS,0
			S9R: begin if(dssck_rise) begin sja1000_wr_n <= 1'b0; st<=S10R; end end //WR,0
			S10R: begin if(dssck_rise) begin st<=S11R; end end 
			S11R: begin if(dssck_rise) begin sja1000_wr_n <= 1'b1; st<=S12R; end end //WR,1
			S12R: begin if(dssck_rise) begin sja1000_cs_n <= 1'b1; st<=S13R; end end //CS,1
			S13R: begin if(dssck_rise) begin st<=S14R; end end 
			S14R: begin if(dssck_rise) begin st<=S15R; end end 
			S15R: begin if(dssck_rise) begin chip_oe <= 1'b0; WR_finish<= 1'b1; st<=S16R; end end //OE,0; WR_finish,1.
			S16R: begin if(dssck_rise) begin WRflag <= 1'b0; WR_finish<= 1'b0; st <= IDLER; end end
			default: st<=IDLER;
		endcase end end

///////////////////////////////////////////////////
assign o_WRflag = WRflag;
assign o_WR_finish = WR_finish;
//////////////////////////////////////////////////
assign o_chip_oe =  WRflag? chip_oe:1'd0;
assign o_sja1000_data_wr = WRflag? sja1000_data_wr:8'd0;
assign o_sja1000_ale = WRflag? sja1000_ale:1'd0;
assign o_sja1000_wr_n = WRflag? sja1000_wr_n:1'd1;
assign o_sja1000_cs_n = WRflag? sja1000_cs_n:1'd1;

endmodule

